package com.flyco.modules.stm.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.flyco.common.api.vo.Result;
import com.flyco.common.system.vo.LoginUser;
import com.flyco.modules.stm.entity.*;
import com.flyco.modules.stm.mapper.StmReplenishmentItemMapper;
import com.flyco.modules.stm.mapper.StmReplenishmentMapper;
import com.flyco.modules.stm.model.ReplenishmentContext;
import com.flyco.modules.stm.service.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 门店要货单
 * @Author: flyco
 * @Date:   2020-11-23
 * @Version: V1.0
 */
@DS("store")
@Service
public class StmReplenishmentServiceImpl extends ServiceImpl<StmReplenishmentMapper, StmReplenishment> implements IStmReplenishmentService {
	@Autowired
	private StmReplenishmentMapper stmReplenishmentMapper;
	@Autowired
	private StmReplenishmentItemMapper stmReplenishmentItemMapper;
	@Autowired
	private IStmReplenishmentItemService stmReplenishmentItemService;
	@Autowired
	private IStmBizInoutRelationService stmBizInoutRelationService;
	@Autowired
	private IOaWldbService oaWldbService;
	@Autowired
	private IStmSkuMaterialService stmSkuMaterialService;

	@Transactional
	@Override
	public Result<?> apply(Integer status, List<Long> ids) {
		List<StmReplenishment> replenishmentList = this.list(Wrappers.lambdaQuery(StmReplenishment.class).in(StmReplenishment::getId, ids));
		List<Long> collect = replenishmentList.stream().filter(q -> q.getStatus() != 3).map(StmReplenishment::getId).collect(Collectors.toList());
		if(!collect.isEmpty()){
			return Result.error("当前发货单状态不允许审批:"+collect);
		}

		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if(status!=3){
			ids.forEach(id-> applyOneDeny(id,sysUser.getRealname()));
			return Result.ok("取消成功");
		}else{
			Map<Long, StmReplenishment> replenishmentMap = replenishmentList.stream().collect(Collectors.toMap(StmReplenishment::getId, a->a));
			Map<Long, List<StmReplenishmentItem>> itemMap = stmReplenishmentItemService.list(Wrappers.lambdaQuery(StmReplenishmentItem.class).in(StmReplenishmentItem::getReplenishmentId, ids))
					.stream().collect(Collectors.groupingBy(StmReplenishmentItem::getReplenishmentId));
			ids.forEach(id-> applyOnePass(replenishmentMap.get(id),itemMap.get(id),sysUser.getRealname()));
			return Result.ok("审批成功");
		}
	}

	@Override
	public Result<ReplenishmentContext> pushOABefore(OaPushDTO oaPushDTO, String userName) {
		//查询要货信息
		StmReplenishment stmReplenishment = this.getById(oaPushDTO.getId());
		if(stmReplenishment==null){
			return Result.fail("查询的信息不存在");
		}
		if(stmReplenishment.getStatus()!=1){
			return Result.fail("要货单状态不正确");
		}
		if(StrUtil.isBlank(stmReplenishment.getSapAddressCode())){
			return Result.fail("历史要货单，请联系管理员维护SAP编码");
		}

		//查询要货单明细
		List<StmReplenishmentItem> itemList = stmReplenishmentItemService.list(Wrappers.lambdaQuery(StmReplenishmentItem.class).eq(StmReplenishmentItem::getReplenishmentId, stmReplenishment.getId()));

		//查询物料编码。key：productId
		Map<Long,List<StmSkuMaterial>> sapItemCodeMap = stmSkuMaterialService.list(Wrappers.lambdaQuery(StmSkuMaterial.class)
				.in(StmSkuMaterial::getProductId,itemList.stream().map(StmReplenishmentItem::getProductId).collect(Collectors.toList()))
				.orderByDesc(StmSkuMaterial::getStartTime))
				.stream().collect(Collectors.groupingBy(StmSkuMaterial::getProductId));

		//检查物料编码是否维护
		List<String> collect = itemList.stream().filter(q -> sapItemCodeMap.get(q.getProductId()) == null).map(StmReplenishmentItem::getProductSn).collect(Collectors.toList());
		if(!collect.isEmpty()){
			return Result.fail("物料编码没有维护："+ collect);
		}

		//更新要货单状态1->3
		StmReplenishment replenishment = new StmReplenishment();
		replenishment.setStatus(3);
		replenishment.setConfirmSales(userName);
		replenishment.setConfirmTime(new Date());
		boolean update = this.update(replenishment, Wrappers.lambdaUpdate(StmReplenishment.class)
				.eq(StmReplenishment::getId, stmReplenishment.getId()).eq(StmReplenishment::getStatus, 1));
		if(!update){
			return Result.fail("要货单状态更新失败");
		}

		ReplenishmentContext replenishmentContext = new ReplenishmentContext();
		replenishmentContext.setStmReplenishment(stmReplenishment);
		replenishmentContext.setItemList(itemList);
		replenishmentContext.setSapItemCodeMap(sapItemCodeMap);

		return Result.success(replenishmentContext);
	}

	private void applyOnePass(StmReplenishment stmReplenishment, List<StmReplenishmentItem> itemList, String applyName){
		StmReplenishment replenishment = new StmReplenishment();
		replenishment.setId(stmReplenishment.getId());
		replenishment.setStatus(5);
		replenishment.setConfirmSales(applyName);
		replenishment.setConfirmTime(new Date());
		this.updateById(replenishment);

		//修改明细的发货数量为要货数量
		List<StmReplenishmentItem> collect = itemList.stream().map(one -> {
			StmReplenishmentItem stmReplenishmentItem = new StmReplenishmentItem();
			stmReplenishmentItem.setId(one.getId());
			stmReplenishmentItem.setSendQty(one.getProductQty());
			return stmReplenishmentItem;
		}).collect(Collectors.toList());
		stmReplenishmentItemService.updateBatchById(collect);

		//创建收货关联表记录
		createStockIn(stmReplenishment,applyName);
	}

	/**
	 * 要货单收货信息初始化
	 */
	private void createStockIn(StmReplenishment stmReplenishment, String applyName){
		Date date = new Date();
		StmBizInoutRelation stmBizInoutRelation = new StmBizInoutRelation();
		stmBizInoutRelation.setPartnerId(stmReplenishment.getPartnerId());
		//入库门店信息
		stmBizInoutRelation.setStoreId(stmReplenishment.getStoreId());
		stmBizInoutRelation.setStoreName(stmReplenishment.getStoreName());
		//发货门店信息
		stmBizInoutRelation.setSourceStoreId(0L);
		stmBizInoutRelation.setSourceStoreName("总仓");
		stmBizInoutRelation.setStatus(1);
		stmBizInoutRelation.setType("STOCK_IN");
		stmBizInoutRelation.setStockBizType("STOCK_IN_TYPE_PURCH");
		stmBizInoutRelation.setSourceType("RECEIPT_TYPE_REPLENISHMENT");
		stmBizInoutRelation.setSourceId(stmReplenishment.getId());
		stmBizInoutRelation.setCreateBy(applyName);
		stmBizInoutRelation.setCreateTime(date);
		boolean inoutSaveResult = stmBizInoutRelationService.save(stmBizInoutRelation);
		if (!inoutSaveResult) {
			throw new RuntimeException("入库记录保存失败,stmReplenishmentId="+stmReplenishment.getId());
		}
	}

	/**
	 * 取消要货单
	 */
	private void applyOneDeny(Long id, String applyName){
		StmReplenishment stmReplenishment = new StmReplenishment();
		stmReplenishment.setId(id);
		stmReplenishment.setStatus(4);
		stmReplenishment.setCancelSales(applyName);
		stmReplenishment.setCancelTime(new Date());
		this.updateById(stmReplenishment);
	}

	@Override
	@Transactional
	public void saveMain(StmReplenishment stmReplenishment, List<StmReplenishmentItem> stmReplenishmentItemList) {
		stmReplenishmentMapper.insert(stmReplenishment);
		for(StmReplenishmentItem entity:stmReplenishmentItemList) {
			//外键设置
			entity.setReplenishmentId(stmReplenishment.getId());
			stmReplenishmentItemMapper.insert(entity);
		}
	}

	@Override
	@Transactional
	public void updateMain(StmReplenishment stmReplenishment,List<StmReplenishmentItem> stmReplenishmentItemList) {
		stmReplenishmentMapper.updateById(stmReplenishment);
		
		//1.先删除子表数据
		stmReplenishmentItemMapper.deleteByMainId(stmReplenishment.getId());
		
		//2.子表数据重新插入
		for(StmReplenishmentItem entity:stmReplenishmentItemList) {
			//外键设置
			entity.setReplenishmentId(stmReplenishment.getId());
			stmReplenishmentItemMapper.insert(entity);
		}
	}

	@Override
	@Transactional
	public void delMain(Long id) {
		stmReplenishmentItemMapper.deleteByMainId(id);
		stmReplenishmentMapper.deleteById(id);
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			stmReplenishmentItemMapper.deleteByMainId(Long.valueOf(id.toString()));
			stmReplenishmentMapper.deleteById(id);
		}
	}
	
}
